// 现代 JavaScript 解构赋值和展开运算符
// 作者：AI助手
// 最后更新：2024年

/**
 * 解构赋值和展开运算符是 ES6 中最强大的特性之一
 * 1. 解构赋值：从数组和对象中提取值，对变量进行赋值
 * 2. 展开运算符：展开数组、对象或其他可迭代对象
 */

// 1. 数组解构
// 1.1 基本数组解构
const colors = ['红', '绿', '蓝'];
const [red, green, blue] = colors;
console.log(red, green, blue);

// 1.2 跳过某些元素
const numbers = [1, 2, 3, 4, 5];
const [first, , third, ...rest] = numbers;
console.log(first, third, rest); // 1, 3, [4, 5]

// 1.3 默认值
const [name = '匿名', age = 18] = ['张三'];
console.log(name, age); // 张三, 18

// 2. 对象解构
// 2.1 基本对象解构
const person = {
    name: '李四',
    age: 30,
    city: '上海'
};
const { name: userName, age: userAge, city } = person;
console.log(userName, userAge, city);

// 2.2 嵌套对象解构
const student = {
    name: '王五',
    scores: {
        math: 95,
        english: 85,
        science: {
            physics: 88,
            chemistry: 90
        }
    }
};

const { 
    scores: { 
        math, 
        science: { physics } 
    } 
} = student;
console.log(math, physics); // 95, 88

// 3. 展开运算符
// 3.1 数组展开
const fruits = ['苹果', '香蕉'];
const moreFruits = ['橙子', ...fruits, '葡萄'];
console.log(moreFruits);

// 3.2 对象展开
const defaults = {
    theme: 'light',
    fontSize: 14
};
const userPreferences = {
    ...defaults,
    fontSize: 16,
    language: 'zh-CN'
};
console.log(userPreferences);

// 4. 实际应用示例
// 4.1 函数参数解构
function printUserInfo({ name, age, address: { city } = {} } = {}) {
    console.log(`${name || '匿名用户'} (${age || '未知年龄'}) 来自 ${city || '未知城市'}`);
}

printUserInfo({ name: '赵六', age: 25, address: { city: '北京' } });
printUserInfo({}); // 使用默认值
printUserInfo(); // 完全使用默认值

// 4.2 API响应处理
const apiResponse = {
    code: 200,
    data: {
        user: {
            id: 1,
            name: '张三',
            contacts: {
                email: 'zhangsan@example.com',
                phone: '123-4567-8900'
            }
        },
        settings: {
            newsletter: true,
            theme: 'dark'
        }
    }
};

// 提取需要的数据
const {
    data: {
        user: { name: userName2, contacts: { email } },
        settings: { theme }
    }
} = apiResponse;

console.log(userName2, email, theme);

// 4.3 数组操作
// 复制和合并数组
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const copyArr = [...arr1]; // 浅拷贝
const mergedArr = [...arr1, ...arr2];
// 深拷贝
const obj = { a: 1, b: { c: 2 } };
const deepCopy = JSON.parse(JSON.stringify(obj));
deepCopy.b.c = 3; // 不会影响原对象
console.log(obj.b.c); // 输出 2


// 4.4 对象操作
// 合并对象
const defaultConfig = {
    host: 'localhost',
    port: 3000,
    timeout: 5000
};

const userConfig = {
    port: 8080,
    ssl: true
};

const finalConfig = {
    ...defaultConfig,
    ...userConfig,
    timestamp: Date.now()
};

console.log(finalConfig);

// 5. 最佳实践
// ✅ 使用解构来获取函数返回值
function getCoordinates() {
    return [120.5, 30.5];
}

const [longitude, latitude] = getCoordinates();

// ✅ 解构用于交换变量
let a = 1, b = 2;
[a, b] = [b, a];

// ✅ 使用展开运算符复制对象时添加新属性
const originalUser = { name: '张三', age: 25 };
const userWithRole = { ...originalUser, role: 'admin' };

// ❌ 避免过度解构
// const { a: { b: { c: { d } } } } = complexObject; // 可读性差

// ❌ 避免在不必要时使用展开
// const single = [...'Hello']; // 除非真的需要将字符串转换为字符数组 